package tt.dz.egobus.servicemanager.controller.carregister;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import tt.dz.egobus.servicemanager.base.controller.EntityController;
import tt.dz.egobus.servicemanager.base.service.ExtendBaseService;
import tt.dz.egobus.servicemanager.bean.ServiceManagerCodeStatus;
import tt.dz.egobus.servicemanager.core.exception.BusinessException;
import tt.dz.egobus.servicemanager.entities.Bus;
import tt.dz.egobus.servicemanager.entities.BusRegisterService;
import tt.dz.egobus.servicemanager.service.BusRegisterServiceService;
import tt.dz.egobus.servicemanager.service.BusService;
import tt.dz.egobus.servicemanager.vo.BusRegisterServiceViewVo;
import tt.dz.egobus.servicemanager.vo.BusServiceViewVo;
import tt.dz.egobus.servicemanager.vo.JsonBack;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static tt.dz.egobus.servicemanager.bean.ServiceManagerCodeStatus.*;

/**
 * @author Anson
 * @date 17-3-16
 * @name 车辆注册服务
 * @since 1.0.1
 */
@RestController
@RequestMapping("/busRegister")
public class BusRegisterServiceController extends EntityController<BusRegisterService, BusRegisterServiceViewVo, String> {
    private static final Logger LOGGER = LoggerFactory.getLogger(BusRegisterServiceController.class);

    @Autowired
    @Qualifier("busRegisterServiceServiceImpl")
    private BusRegisterServiceService service;

    @Autowired
    @Qualifier("busServiceImpl")
    private BusService busService;


    @Override
    protected ExtendBaseService<BusRegisterService, String> getSelfService() {
        return this.service;
    }

    @Override
    protected BusRegisterServiceViewVo newViewVo() {
        return new BusRegisterServiceViewVo();
    }


    /**
     * @param busId 车辆id
     * @author Anson
     * @date 17-4-17
     * @name 根据车辆查询可以绑定的服务
     * @since 1.0.4
     */
    @RequestMapping("/busQueryAbleService")
    public JsonBack<List<BusServiceViewVo>> queryBusAbleBindServices(@RequestParam("busId") String busId) {
        JsonBack<List<BusServiceViewVo>> back = null;
        try {
            List<tt.dz.egobus.servicemanager.entities.BusService> list
                    = this.service.queryBusAbleBindServices(busId);
            back = JsonBack.success(this.busServicePojoConvertView(list));
        } catch (BusinessException e) {
            back = JsonBack.error(e);
            LOGGER.error("据车辆查询可以绑定的服务异常", e);
        } catch (Exception e) {
            back = JsonBack.error(SYSTEM_CODE_ERROR);
            LOGGER.error("据车辆查询可以绑定的服务异常", e);
        }
        return back;
    }

    /**
     * @param list pojo集合
     * @author Anson
     * @date 17-4-17
     * @name 转换pojo集合为vo集合
     * @since 1.0.4
     */
    protected List<BusServiceViewVo> busServicePojoConvertView(
            List<tt.dz.egobus.servicemanager.entities.BusService> list) {
        if (list == null) {
            return null;
        }
        List<BusServiceViewVo> datas = new ArrayList<BusServiceViewVo>();
        BusServiceViewVo v = null;
        for (tt.dz.egobus.servicemanager.entities.BusService e : list) {
            v = new BusServiceViewVo();
            if (v == null) {
                continue;
            }
            v = v.view(e);
            datas.add(v);
        }
        return datas;
    }


    /**
     * @param busRegisterService 车辆的注册服务
     * @author Anson
     * @date 17-4-6
     * @name 车辆有效注册服务的时候存在重复注册
     * @since 1.0.4
     */
    @Override
    protected void preInsertHandler(BusRegisterService busRegisterService) throws BusinessException {
        String busId = busRegisterService.getBusId();
        if (StringUtils.isEmpty(busId)) {
            throw new BusinessException(PARAM_ILLEGAL_ERROR.getCodeStatus());
        }
        Bus bus = this.busService.get(busId);
        if (null == bus) {
            throw new BusinessException(BUS_NOT_EXIT.getCodeStatus());
        }

        if (busRegisterService.isValidate()) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("eq#busId", busRegisterService.getBusId());
            params.put("eq#busServiceId", busRegisterService.getBusServiceId());
            params.put("eq#isValidate", true);
            int count = this.service.count(params);
            if (count > 0) {
                throw new BusinessException(PARAM_BUS_REGISTER_REPEAT_ERROR.getCodeStatus());
            }
            //新增注册关系的时候
            this.validateBusRegister(bus, false);
        }
    }

    /**
     * @param busRegisterService 车辆的注册服务
     * @author Anson
     * @date 17-4-6
     * @name 确认更新当前车辆状态 从un_active --> not_use
     * @since 1.0.4
     */
    @Override
    protected void postInsertHandler(BusRegisterService busRegisterService) throws BusinessException {
        String busId = busRegisterService.getBusId();
        if (StringUtils.isEmpty(busId)) {
            throw new BusinessException(PARAM_ILLEGAL_ERROR.getCodeStatus());
        }
        Bus bus = this.busService.get(busId);
        int count = getBusRegisterCount(busId);
        //处理当前车未激活或者未使用
        this.dealBusRegisterStatus(bus, count);
    }


    /**
     * @param busRegisterService 车辆的注册服务
     * @author Anson
     * @date 17-4-6
     * @name 当前更新注册的时候存在以前相同的服务注册
     * 排除当前的注册关系
     * @since 1.0.4
     */
    @Override
    protected void preUpdateHandler(BusRegisterService busRegisterService) throws BusinessException {
        String busId = busRegisterService.getBusId();
        if (StringUtils.isEmpty(busId)) {
            throw new BusinessException(PARAM_ILLEGAL_ERROR.getCodeStatus());
        }
        Bus bus = this.busService.get(busId);

        if (busRegisterService.isValidate()) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("eq#id", busRegisterService.getBusId());
            params.put("eq#busId", busRegisterService.getBusId());
            params.put("eq#busServiceId", busRegisterService.getBusServiceId());
            params.put("eq#isValidate", true);
            int count = this.service.count(params);
            if (count > 0) {
                throw new BusinessException(PARAM_BUS_REGISTER_REPEAT_ERROR.getCodeStatus());
            }
            //有效的时候
            this.validateBusRegister(bus, false);
        } else {
            //失效的时候
            this.validateBusRegister(bus, true);
        }
    }

    @Override
    protected void postUpdateHandler(BusRegisterService busRegisterService) throws BusinessException {
        String busId = busRegisterService.getBusId();
        if (StringUtils.isEmpty(busId)) {
            throw new BusinessException(PARAM_ILLEGAL_ERROR.getCodeStatus());
        }
        Bus bus = this.busService.get(busId);
        if (null == bus) {
            throw new BusinessException(BUS_NOT_EXIT.getCodeStatus());
        }
        int count = getBusRegisterCount(busId);
        //处理当前车未激活或者未使用
        this.dealBusRegisterStatus(bus, count);
    }

    /**
     * 存在注册服务的个数不为0的时候，更改当前为未使用的状态
     * 当前车辆注册服务的个数为0，则表示未激活
     *
     * @param bus
     * @param count
     * @author Anson
     * @date 17-5-3
     * @name 处理处理当前车未激活或者未使用
     * @since 1.0.4
     */
    private void dealBusRegisterStatus(Bus bus, int count) {
        if (count > 0 && bus.assertNotActive()) {
            //存在注册服务的个数不为0的时候，更改当前为未使用的状态
            bus.setBindStatus();
            this.busService.update(bus);
        } else if (count == 0) {
            //当前车辆注册服务的个数为0，则表示未激活
            bus.setUnRegisterStatus();
            this.busService.update(bus);
        }
    }

    /**
     * @param id 当前车辆的注册服务id
     * @author Anson
     * @date 17-4-6
     * @name 在预先删除的id中处理
     * @since 1.0.4
     */
    @Override
    protected void preDeleteHandler(String id) throws BusinessException {
        if (StringUtils.isEmpty(id)) {
            throw new BusinessException(PARAM_ILLEGAL_ERROR.getCodeStatus());
        }
        BusRegisterService busRegisterService = this.service.get(id);
        Bus bus = busRegisterService.getBus();
        if (null == bus) {
            throw new BusinessException(BUS_NOT_EXIT.getCodeStatus());
        }
        this.validateBusRegister(bus, true);
        int count = getBusRegisterCount(busRegisterService.getBusId(), id);
        if (count == 0) {
            bus.setNoActive();
            this.busService.update(bus);
        }
    }

    /**
     * @param bus 当前绑定车辆
     * @param isDelete 是否是当前车辆注册服务删除或者失效
     * @author Anson
     * @date 17-6-5
     * @name 判断当前车辆是否处于状态可修改的阶段
     * 添加当前车辆注册服务状态的时候，当前车辆处于不可用的状态（异常，修复，损坏）以及正在使用中的状态使不能修改其状态
     * 失效当前车辆注册服务的时候，拖当前处于使用中的时候，则不能修改其状态
     * @since 1.0.4
     */
    private void validateBusRegister(Bus bus, boolean isDelete) {
        ServiceManagerCodeStatus status = null;
        if (bus.assertUsed()) {
            //凡是处于使用中，都不能修改其状态
            status = BUS_BUSY;
        } else if (isDelete && (!bus.isAbleUnbingRegister())) {
            //删除注册关系的时候，凡是处于使用中，都不能修改其状态
            status = BUS_BUSY;
        } else if ((!isDelete) && (!bus.isAbleBindRegister())) {
            //当前新增车辆注册状态的时候
            status = BUS_IN_UN_USED;
        }
        if (status != null) {
            throw new BusinessException(status.getCodeStatus());
        }
    }


    /**
     * @param busId
     * @author Anson
     * @date 17-4-21
     * @name 判断当前注册服务的个数
     * @since 1.0.4
     */
    private int getBusRegisterCount(String busId) {

        return this.getBusRegisterCount(busId, null);
    }

    /**
     * @param busId
     * @param excludeRegisterId 排除的注册id
     * @author Anson
     * @date 17-4-21
     * @name 判断当前注册服务的个数
     * @since 1.0.4
     */
    private int getBusRegisterCount(String busId, String excludeRegisterId) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("eq#busId", busId);
        params.put("eq#isValidate", true);
        if (!StringUtils.isBlank(excludeRegisterId)) {
            params.put("ne#id", excludeRegisterId);
        }
        return this.service.count(params);
    }
}